from os import remove, listdir, rename

"""
文件批处理相关：
"""
__all__ = {
    'list_from_dir': '返回目录下列表',
    'list_filter': '根据特征过滤列表元素',
    'list_castrated': '删除列表内所有元素被要求删除的内容',
    'list_give_tail': '在列表元素末尾添加内容',
    'file_sort': '根据特征序列化列表',
    'file_delete': '删除列表记录的文件',
    'file_rename': '重命名列表记录的文件',

    'need_filelist': '返回类型文件名列表',
    'num_filelist': '返回序列化文件名列表',
    'delete_type_file': '删除类型文件',
}


# 零件 ###############################################################

def list_from_dir(path: str = '') -> list:
    """
    # 返回{path}目录下文件名列表

    :param path: 目录路径，默认为当前目录
    :return: 全部文件名
    """
    # 对路径预处理,路径转义为/且对无效值默认为当前目录
    path = path.replace("\\", '/')
    path = '.' if path.find('/') == -1 else path

    # 获取文件路径下全部文件名，非本地则额外增加路径前缀
    lis = listdir(path)
    if path != '.':
        for i in range(len(lis)):
            lis[i] = path + lis[i]

    return lis


def list_filter(field: str, lis: list) -> list:
    """
    # 对列表字符串根据{name}筛除

    :param field: 需要筛除的字段
    :param lis: 筛除对象，字符串列表
    :return: 过筛后字符串列表
    """
    # 捕获目录下文件名，并在判断后返回，判断方式为简易的字符串判断
    tmp = []
    for li in lis:
        if li.find(field) != -1:
            tmp.append(li)

    return tmp


def list_castrated(field: str, lis: list) -> list:
    """
    # 去除列表共有项

    :param field: 需要删除对象
    :param lis: 列表对象
    :return: 处理完列表
    """
    # 查出自左至右第一次检测位置并插值，若无则返回原本内容
    tmp = []
    for li in lis:
        spos = li.find(field)
        if spos == -1:
            tmp.append(li)
        else:
            epos = spos + len(field)
            tmp.append(li[:spos] + li[epos:])

    return tmp


def list_give_tail(tail: str, lis: list) -> list:
    """
    # 给列表加个小尾巴~

    :param tail: 尾巴
    :param lis: 数据样本
    :return: 加完尾巴的东西
    """
    # 附加小尾巴~
    tmp = []
    for li in lis:
        tmp.append(li + tail)

    return tmp


def file_delete(lis: list) -> None:
    """批量化删除文件"""
    for file in lis:
        remove(file)


def file_rename(lis: list, tail=None) -> None:
    """文件重命名"""
    # 先打乱文件顺序和序列，防止因已经存在命名而无法重写
    tmp = []
    for file in lis:
        name = file[file.rfind('/') + 1:]
        path = file[:file.rfind('/') + 1]
        na = path + '_100000_' + name
        tmp.append(na)
        rename(file, na)
    # 序列化重命名
    num = 0
    for file in tmp:
        name = file[file.rfind('/') + 1:]
        path = file[:file.rfind('/') + 1]
        tail = name[name.rfind('.'):] if tail is None else tail
        num += 1
        na = path + str(num) + tail
        rename(file, na)


def file_sort(trait: list, lis: list) -> list:
    """
    # 序列化排序结果

    :param trait: 提取内容的特征,如['[',']']
    :param lis: 素材
    :return: 排序后名单
    """
    # 提取为{原本素材:特征值,...}的字典内容
    tmp = {}
    for li in lis:
        ppos = li.rfind('/')
        name = li[ppos+1:] if ppos != -1 else li  # 滤除路径
        spos = name.rfind(trait[0])+1 if trait[0] is not None else None
        if spos == -1:
            continue
        epos = name.rfind(trait[1])
        v = name[spos:epos]
        try:
            tmp[li] = int(v)
        except:
            pass
    # 排序后返回结果
    tmp = dict(sorted(tmp.items(), key=lambda e: e[1]))

    tm = []
    for k in tmp:
        tm.append(k)
    return tm


# 组装 ###############################################################

def need_filelist(path=None, field=None) -> list:
    """获取目录下所需类型文件列表"""
    path = input('文件路径>') if path is None else path
    field = input('文件类型>') if field is None else field

    lis = list_from_dir(path)
    lis = list_filter(field, lis)
    return lis


def num_filelist(path=None, field=None, trait=None) -> list:
    """获取序列化排序结果"""
    # trait 为 [开始,结束] 标志，它将根据范围内容排序，请确保提取内容可转为int类型
    # ['', '.'] - 文件名  ['[', ']'] - 标记
    trait = ['[', ']'] if trait is None else trait

    lis = need_filelist(path, field)
    lis = file_sort(trait, lis)
    return lis


def rename_order(path=None, field=None, trait=None):
    """按照特征参数序列化重命名"""
    lis = num_filelist(path, field, trait)
    file_rename(lis)


def delete_type_file(path=None, field=None):
    """删除类型文件"""
    lis = need_filelist(path, field)
    file_delete(lis)


# 注意！当声明类时，请将任何过程都请填入def方法！因为编译器会在初始化过程中，试图运行它！！！！！
class UI:
    """简易功能ui使用"""
    path = r'E:\搞事\图像处理\Zako\图像工厂\1/'

    def __init__(self):
        while True:
            print('当前目录：' + self.path)
            print('1 - 序列化重命名')
            print('2 - 类型删除')

            x = input('>>')
            if x == '1':
                rename_order(path=self.path)
            elif x == '2':
                delete_type_file(path=self.path)


if __name__ == "__main__":
    UI()
